extern int main();
extern void SystemInit();
extern void __libc_init_array();

#define isr_nmi NMI_Handler
#define isr_hardfault HardFault_Handler
#define isr_svcall SVC_Handler
#define isr_pendsv PendSV_Handler
#define isr_systick SysTick_Handler
#define isr_irq0 TIMER0_IRQ_0_Handler
#define isr_irq1 TIMER0_IRQ_1_Handler
#define isr_irq2 TIMER0_IRQ_2_Handler
#define isr_irq3 TIMER0_IRQ_3_Handler
#define isr_irq4 TIMER1_IRQ_0_Handler
#define isr_irq5 TIMER1_IRQ_1_Handler
#define isr_irq6 TIMER1_IRQ_2_Handler
#define isr_irq7 TIMER1_IRQ_3_Handler
#define isr_irq8 PWM_IRQ_WRAP_0_Handler
#define isr_irq9 PWM_IRQ_WRAP_1_Handler
#define isr_irq10 DMA_IRQ_0_Handler
#define isr_irq11 DMA_IRQ_1_Handler
#define isr_irq12 DMA_IRQ_2_Handler
#define isr_irq13 DMA_IRQ_3_Handler
#define isr_irq14 USBCTRL_IRQ_Handler
#define isr_irq15 PIO0_IRQ_0_Handler
#define isr_irq16 PIO0_IRQ_1_Handler
#define isr_irq17 PIO1_IRQ_0_Handler
#define isr_irq18 PIO1_IRQ_1_Handler
#define isr_irq19 PIO2_IRQ_0_Handler
#define isr_irq20 PIO2_IRQ_1_Handler
#define isr_irq21 IO_IRQ_BANK0_Handler
#define isr_irq22 IO_IRQ_BANK0_NS_Handler
#define isr_irq23 IO_IRQ_QSPI_Handler
#define isr_irq24 IO_IRQ_QSPI_NS_Handler
#define isr_irq25 SIO_IRQ_FIFO_Handler
#define isr_irq26 SIO_IRQ_BELL_Handler
#define isr_irq27 SIO_IRQ_FIFO_NS_Handler
#define isr_irq28 SIO_IRQ_BELL_NS_Handler
#define isr_irq29 SIO_IRQ_MTIMECMP_Handler
#define isr_irq30 CLOCKS_IRQ_Handler
#define isr_irq31 SPI0_IRQ_Handler
#define isr_irq32 SPI1_IRQ_Handler
#define isr_irq33 UART0_IRQ_Handler
#define isr_irq34 UART1_IRQ_Handler
#define isr_irq35 ADC_IRQ_FIFO_Handler
#define isr_irq36 I2C0_IRQ_Handler
#define isr_irq37 I2C1_IRQ_Handler
#define isr_irq38 OTP_IRQ_Handler
#define isr_irq39 TRNG_IRQ_Handler
#define isr_irq40 0
#define isr_irq41 0
#define isr_irq42 PLL_SYS_IRQ_Handler
#define isr_irq43 PLL_USB_IRQ_Handler
#define isr_irq44 POWMAN_IRQ_POW_Handler
#define isr_irq45 POWMAN_IRQ_TIMER_Handler

/*
naked 属性 告诉编译器 不生成 压栈汇编 push {r7, lr}等指令

ARM 状态与 Thumb 状态
有些处理器同时支持 ARM 和 Thumb 指令集,通过 BX 或 BLX 指令进行切换,当指令 BX
跳转地址的 LSB 位为 1,表示切换到 Thumb 状态,为 0 则切换到 ARM 状态。

无论是 ARM 还是
Thumb,其指令在存储器中都是边界对齐的（2字节或4字节对齐）,也就是地址的最低位总是
0。 因此,在执行跳转过程中,PC 寄存器中的最低位被舍弃,不起作用。 在 BX
指令的执行过程中,最低位正好被用作状态判断的标志,不会造成存储器访问不对齐的错误。

Cortex-M 系列处理器不支持 ARM 指令,因此也不存在 ARM
状态,所以反汇编中的函数地址最低位都是 1

bin 部分数据含义
0x8000000-0x8000003  ：中断向量表定义 栈顶指针,SRAM最大地址  送  SP
0x8000004-0x8000008  : 存储 reset中断函数地址（_start_func） 送  PC
 */

// reset handle

__attribute__((naked)) void _start_func()
{
 
	extern unsigned int _sidata, _sdata, _edata, _sbss, _ebss;

	unsigned int *sdata;
	unsigned int *data_atflash;

	// copy data from flash to sram
	sdata = &_sdata;
	data_atflash = &_sidata;
	while (sdata < &_edata)
	{
		*sdata++ = *data_atflash++;
	}

	/*clear bss*/
	sdata = &_sbss;
	while (sdata < &_ebss)
	{
		*sdata++ = 0;
	}
	//__libc_init_array();
	// start newlib._start in newlib/libc/sys/arm/crt0.S
	//_start();
	SystemInit();
	main();
}

/***********************中断向量声明******************************* */
//  声明 中断函数 防止编译器报错
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif

__WEAK void NMI_Handler() {}
__WEAK void HardFault_Handler() {}
__WEAK void SVC_Handler() {}
__WEAK void PendSV_Handler() {}
__WEAK void SysTick_Handler() {}
__WEAK void TIMER0_IRQ_0_Handler() {}
__WEAK void TIMER0_IRQ_1_Handler() {}
__WEAK void TIMER0_IRQ_2_Handler() {}
__WEAK void TIMER0_IRQ_3_Handler() {}
__WEAK void TIMER1_IRQ_0_Handler() {}
__WEAK void TIMER1_IRQ_1_Handler() {}
__WEAK void TIMER1_IRQ_2_Handler() {}
__WEAK void TIMER1_IRQ_3_Handler() {}
__WEAK void PWM_IRQ_WRAP_0_Handler() {}
__WEAK void PWM_IRQ_WRAP_1_Handler() {}
__WEAK void DMA_IRQ_0_Handler() {}
__WEAK void DMA_IRQ_1_Handler() {}
__WEAK void DMA_IRQ_2_Handler() {}
__WEAK void DMA_IRQ_3_Handler() {}
__WEAK void USBCTRL_IRQ_Handler() {}
__WEAK void PIO0_IRQ_0_Handler() {}
__WEAK void PIO0_IRQ_1_Handler() {}
__WEAK void PIO1_IRQ_0_Handler() {}
__WEAK void PIO1_IRQ_1_Handler() {}
__WEAK void PIO2_IRQ_0_Handler() {}
__WEAK void PIO2_IRQ_1_Handler() {}
__WEAK void IO_IRQ_BANK0_Handler() {}
__WEAK void IO_IRQ_BANK0_NS_Handler() {}
__WEAK void IO_IRQ_QSPI_Handler() {}
__WEAK void IO_IRQ_QSPI_NS_Handler() {}
__WEAK void SIO_IRQ_FIFO_Handler() {}
__WEAK void SIO_IRQ_BELL_Handler() {}
__WEAK void SIO_IRQ_FIFO_NS_Handler() {}
__WEAK void SIO_IRQ_BELL_NS_Handler() {}
__WEAK void SIO_IRQ_MTIMECMP_Handler() {}
__WEAK void CLOCKS_IRQ_Handler() {}
__WEAK void SPI0_IRQ_Handler() {}
__WEAK void SPI1_IRQ_Handler() {}
__WEAK void UART0_IRQ_Handler() {}
__WEAK void UART1_IRQ_Handler() {}
__WEAK void ADC_IRQ_FIFO_Handler() {}
__WEAK void I2C0_IRQ_Handler() {}
__WEAK void I2C1_IRQ_Handler() {}
__WEAK void OTP_IRQ_Handler() {}
__WEAK void TRNG_IRQ_Handler() {}
__WEAK void PLL_SYS_IRQ_Handler() {}
__WEAK void PLL_USB_IRQ_Handler() {}
__WEAK void POWMAN_IRQ_POW_Handler() {}
__WEAK void POWMAN_IRQ_TIMER_Handler() {}

/*中断向量表 占用data 区*/
extern unsigned int _end_stack_bottom;
__attribute__((section(".vectors"))) const void *__vectors[] = {
	(void *)(&_end_stack_bottom), /*ram最大地址*/
	/*reset_handler 单片机复位后从这个地址开始运行 */
	/*cortex M只支持thumb2 指令,机器码最低位强制是1,所以地址会+1 */
	_start_func,
	isr_nmi,
	isr_hardfault,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	isr_svcall,
	0,
	0,
	isr_pendsv,
	isr_systick,
	isr_irq0,
	isr_irq1,
	isr_irq2,
	isr_irq3,
	isr_irq4,
	isr_irq5,
	isr_irq6,
	isr_irq7,
	isr_irq8,
	isr_irq9,
	isr_irq10,
	isr_irq11,
	isr_irq12,
	isr_irq13,
	isr_irq14,
	isr_irq15,
	isr_irq16,
	isr_irq17,
	isr_irq18,
	isr_irq19,
	isr_irq20,
	isr_irq21,
	isr_irq22,
	isr_irq23,
	isr_irq24,
	isr_irq25,
	isr_irq26,
	isr_irq27,
	isr_irq28,
	isr_irq29,
	isr_irq30,
	isr_irq31,
	isr_irq32,
	isr_irq33,
	isr_irq34,
	isr_irq35,
	isr_irq36,
	isr_irq37,
	isr_irq38,
	isr_irq39,
	isr_irq40,
	isr_irq41,
	isr_irq42,
	isr_irq43,
	isr_irq44,
	isr_irq45};
